home *** CD-ROM | disk | FTP | other *** search
/ Gigarom 4 / Mac Giga-ROM 4.0 - 1993.toast / FILES / HYP / T-Z / Windoid (Get Info) < prev    next >
Text File  |  1989-02-26  |  63KB  |  1,100 lines

  1. Welcome...
  2.  
  3. This is the first issue of  Windoid - the newsletter for the Apple HyperCard User’s Group.  We hope the user group and newsletter will create a forum for information about HyperCard, including tips and techniques in various accessible formats to make your use of HyperCard even more valuable, flexible, and fun.
  4.  
  5. We will bring you articles written by the development team and will make efforts to take your questions and problems directly to the source for an answer.
  6.  
  7. In addition, and most importantly, Windoid will create a forum for the open sharing of stackware and information.  
  8.  
  9. Bill and Dan have shown a remarkable ability to immediately understand the needs, ideas, and suggestions of HyperCard users.   The members of the team have thus been able to assist greatly in shaping HyperCard into what it is today.  The continuing interest in user input gives users a unique opportunity to help shape HyperCard’s future. 
  10.  
  11. This newsletter provides an opportunity for  its readers to contribute to the continued genesis of HyperCard.  With your assistance we can continue to bring to HyperCard added depth and functionality.  In the back of every issue will be a form for you to keep by your Macintosh™.  This form will give you the unique opportunity to be able to participate in the continued development of HyperCard.  
  12.  
  13. If you have a bug, suggestion, or comment fill 
  14. out the form and send it to:
  15. AHUG
  16. C/O David Leffler
  17. Apple Computer Inc.
  18. MS 27AQ
  19. 20525 Mariani Blvd.
  20. Cupertino, CA  95014
  21.  
  22.  
  23. Or  copy the form's format and AppleLink™ it to:
  24. HYPERBUG$
  25. ====================
  26. Ask the Team...
  27.  
  28. The HyperCard test team has consented to provide us with a series of tips and techniques based on frequent user questions.  Please send in your questions and they will try to answer the most consistently asked.
  29.  
  30. How can I create a script that will enable me to double-click an icon button?
  31.  
  32. Consider creating a button script like the following.
  33. The following handler makes a button that will detect a double-click on itself.  It waits 30 ticks for the 2nd click then times out.
  34. Put this handler into a button’s script, then add whatever special things you want your button to do when double-clicked. Adjust the timeout value if you want it to wait longer (or shorter).   A tick is 1/60th of a second.
  35. on mouseUp
  36.   put the ticks into originalTicks
  37.   repeat until the mouseClick
  38.     if the ticks - originalTicks > 30
  39.      then exit mouseUp
  40.   end repeat
  41.   -- Put here whatever you want the 
  42.   --button to do when double-clicked.
  43.   -- For example:
  44.   Play “Boing”
  45. end mouseUp
  46.  
  47.  
  48. How can I get a word in a field to do something when I click on it?
  49.  
  50. One way would be to put a transparent button over the text.  If you want to be able to move the word around inside the field without having to move the transparent button with it, you can use the following “sticky button” technique.
  51.  
  52.      The following script gets put into the field:
  53. On Mousedown
  54.     Set locktext of me to false
  55.     click at the clickloc
  56.     click at the clickloc
  57.     if the selection is “Apple” then
  58.         answer “What kind of Apple:” with
  59.         “Macintosh” or “Apple II”
  60.     else
  61.         put “I don’t know that word” 
  62.         into msg
  63.     end if
  64.     set locktext of me to true
  65. End Mousedown
  66.  
  67. Note: MouseDown, mouseStillDown, and mouseUp messages only get sent to a field when that field is locked. It is therefore necessary to lock a field when expecting that field to deal with any of these messages.
  68.  
  69. The idea behind sticky buttons is to cause a word to be selected (highlighted) with a single mouse click. ‘The selection’ then becomes a container.
  70.  
  71. In the above script, we first unlock the field so that we can create a selection. Next, we want to make Hypercard believe that we have double clicked a word, when we really have clicked it only once. This is done in the next two lines of the script. Clicking at the clickloc forces Hypercard to click twice at the same location clicked at by the user. A highlighted selection is then created. Once a word is highlighted, we can use the Hypercard function ‘the selection’ to find out what that word is. 
  72.  
  73.     Comparison can be done using multiple IF THEN statements or by the use of a word-list field. In the above script, we do a very simple IF THEN ELSE comparison which only looks for the word APPLE. When found, it puts up a dialog. If any other word is clicked, a generic message is placed in the message box. Remember that you do not need to show the message box every time you want to write into it. Hypercard displays the message box automatically whenever text is placed inside it.
  74.  
  75. How can I find out which line of a field a user has clicked in?
  76.  
  77. It is easy to calculate using information that can be obtained about a given field. 
  78.  
  79. First of all, we can find out what size rectangle a field occupies by using the field property, RECT. Short for rectangle, RECT returns four numbers in a comma separated list. The numbers represent the upper-left and lower-right screen coordinates for that field.
  80. Next, we can find out what the line height of each line of a field is by using the field property, TEXTHEIGHT. As you might have guessed, each line of a field can really be expressed as a multipleof the line height. Unfortunately, we must determine that multiple using the screen coordinates. Here’s a user defined function that will do just that:
  81. Function Clickline
  82.     return ((item 2 of the 
  83.     clickloc - item 2 of the rect of the
  84.     target) div the textheight of the
  85.     target) + 1
  86. End Clickline
  87.  
  88. on openField
  89.     put clickline() into msg
  90.     pass openField
  91. end openField
  92.  
  93. Ignore the openField handler for now, but take a look at the function. As you may remember, the Hypercard function, THE TARGET, returns the name and id of the object which last received a message. Likewise, the Hypercard function THE CLICKLOC returns the horizontal and vertical screen position of the last mouse click as two comma separated integers. With that knowledge, let’s dissect the function Clickline() (yes, you need the parentheses).
  94.  
  95. The function returns an integer which represents the number of the line of any field clicked in. 
  96.  
  97. Here’s how the function determines the field’s line number. First, it takes the vertical location clicked at by the user (item 2 of the clickloc) and subtracts the top of the field (item 2 of the rect) to determine how many pixels are between the top of the field and the location clicked at. Once this is known, determining the line number is a matter of dividing those pixels by the TEXTHEIGHT. This is what the rest of the function does. We add 1 because Clickline() returns a zero for line 1.
  98.  
  99. Clickline() is very flexible. In the openfield handler shown above for example, we use clickline() with a put statement, treating it just like the number it returns. You can also use it with an IF THEN statement or any place where you would use the number itself. All you need do is replace the ‘put line’ of the openfield handler with your script.
  100. What about scrolling fields?
  101.  
  102. An interesting exception arises when using scrolling fields. The above function does not account for lines that may have scrolled off of the screen. It looks only at the visible area of the field. Consider the following function:
  103.  
  104. Function Clickline
  105.     return (((item 2 of the 
  106.     clickloc - item 2 of the rect of the
  107.     target) div the textheight of the
  108.     target) + 1 + trunc(scroll of the
  109.     target/textheight of the target))
  110. End Clickline
  111.  
  112. It adds the number of lines that have scrolled off the screen to the total number of visible lines. The field property SCROLL returns the number of pixels scrolled off the top of the field. When divided by the TEXTHEIGHT, this yields the number of lines. Since a full line may not have scrolled by, it is necessary to truncate the value using the TRUNC function.
  113.  
  114. Put both the function definition and the openfield handler in your home script where they can be used by any field in any stack.
  115.  
  116. How can I hide buttons from command-option key peek?
  117.  
  118. When you don’t want people peeking at your buttons, it is necessary to trap the command and option keys. While there are several ways of doing this, here is one that is simple and works about 99% of the time.
  119.  
  120. The basic idea is to take the user to another card when the command and option keys are both pressed. This can be a “no peeking” card or a rules card or some other kind of card. When the user releases both keys, you then return to the card the user was viewing before trying to peek. Following are the two scripts that accomplish this. Put the top one in your  stack script and the other in the “no peeking” card script.
  121. For the stack script:
  122. On Idle
  123.     if the commandkey is down and 
  124.     the optionkey is down then
  125.         push this card
  126.         go card “no peeking”
  127.     end if
  128. end Idle
  129.  
  130. For the “no peeking” card script:
  131. On Idle
  132.     if the commankey is up and 
  133.     the optionkey is up then
  134.         pop card
  135.     end if
  136. End Idle
  137. ====================
  138. Stack Building Hints
  139. Beware of relying entirely on  “Go Back”  buttons for navigation through your stack.    A good technique is: On openCard  “push recent card”, which remembers where you just came from.  Then when you do a “pop card” you will always go to that recent location.  
  140.  
  141. If you suspect that your pushes and pops are not in sync,  add the following handlers to your stack script to help you sort them out.
  142.  
  143. on pop params
  144.     put the params after msg
  145.     pass pop   
  146. end pop
  147.  
  148. on push params
  149.     put the params after msg
  150.     pass push
  151. end push
  152. ====================
  153.  
  154. Power User Tips
  155. •  Create a button on your Home card with a script that says, 'go to stack "the stack you want”.'  When you click on it, not finding a stack by that name it will put up SFGetfile asking “Where is the stack you want?” 
  156. •  To zoom directly to the script of an object, hold down the Shift key while double clicking on the object, or while choosing Object "Info...".
  157. •  Do not name a button or a field with a name that begins with a numeric character.  This causes problems in that  if you ask for a button “1812” HyperCard looks for the button whose number, not name, is 1812.
  158. •  In the button or field tools, holding the shift key down when dragging constrains the movement horizontally or vertically, making it easy to drag in a straight line.
  159. •  With any tool, Option-Drag in Fatbits allows you to scroll the screen.
  160. •  To “pre warm” the cards in a stack so that “show all cards” will really cook through the stack, put an "on openStack" script that locks the screen, shows all cards, and then unlocks the screen.  This quickly and invisibly caches all the cards, so that "show card" scripts will work at optimum speed.
  161. •  If you are running on a Mac II and want to see Visual Effects, be sure to set the monitor to 2 bit mode.
  162. ============
  163. Volume 1 Number 2
  164.  
  165. Windoid provides an opportunity for its readers to contribute to the ongoing growth and excellence of HyperCard™.  With your assistance we can continue to bring to HyperCard added depth and functionality.  In the back of every issue will be a form for you to keep by your Macintosh™.  This form will give you the unique opportunity to be able to participate in the continued development of HyperCard.  
  166.  
  167. If you have a bug, suggestion, comment, or just want to know the best way to do something in HyperCard, you can fill out the form and send it to:  AHUG c/o David Leffler,
  168. Apple Computer, Inc., MS/27-AQ, 10500 N. DeAnza Blvd.,
  169. Cupertino, CA 95014.  Or copy the format and Apple-Link™ it to HYPERBUG$.
  170.  
  171.  
  172. We will read all the forms returned and address questions 
  173. that are being asked by HyperCard users.  We will ask the team and provide you with an answer and publish the answers in this newsletter.  In this way we can provide for your needs in future versions of HyperCard.
  174.  
  175. Windoid is trying to make a difference in the way that you work with HyperCard.  We would like your input.  What sort of stacks are you using, what kinds of stacks are you building, and what are some of the joys and frustrations you are experiencing.  We really want to know!
  176.  
  177. Bill and Dan are receptive to user input and this is your chance to make a difference in the word.
  178.  
  179. ==========
  180.  
  181. In this second issue of Windoid, we have listened to those who have made a contribution and have needed information.  In this issue we will address some of the areas that people have questioned us about and talk in depth about importing text files.
  182.  
  183. ==========
  184.  
  185. Importing Text
  186. by Gary Bond
  187. Many people have large amounts of data stored in text files.  They would like to move this information into Hyper-Card stacks.  There are many ways to import files, and we have included in this issue what we feel addresses most of your needs.  We have sifted through the many different ways our users have come up with to import files, and we have chosen a few of the most simple and flexible.
  188.  
  189. This issue will deal with import scripts, and next issue will deal with planning the stack and the Universal Import Button.
  190.  
  191. When importing text into Hypercard, you must consider how you want the text to appear. Should it fill a single field? Should it create new fields and new cards for each imported text record? How much of a field should you fill with text? Will it appear in scrolling fields? What kind of text will be imported? These are all questions that need to be answered before you begin writing your script. This article will explore the two kinds of text and answer some of these questions.
  192.  
  193. For the most part, there are two types of text files. The first is the common document file which is usually nothing more than a Macwrite or Word document saved as a text file. All of the characters in this kind of file are usually in printable ASCII format.
  194.  
  195. The second kind of text file is sometimes generated by a database product such as Omnis or 4th Dimension. This kind of file is broken down into two parts. These parts are records (which are considered to be separate and distinct groups of information) and fields (which are subunits of information within records). A record can contain several fields with each field capable of holding a different kind of information. In a mailing list for example, each person in the mailing list would be a record in the database while the information about that person such as their name, address, city, state and zip would be fields of information within the individual records. Notice that each record in this kind of file has the same number of fields.
  196.  
  197. Below are some common scripts for reading and writing the first kind of text file:
  198.  
  199. Simple read from a text file:
  200.  
  201. On mouseup
  202.     Open file filename
  203.     Repeat
  204.         Read from file filename for 16384 —fastest/most efficient read
  205.          If it is empty then exit repeat —leave when out of characters
  206.          Put it after var —continue to build a variable with incoming text
  207.          —Could also put after a field but must respect the 32K field limit
  208.      End repeat
  209.     Close file filename
  210. End mouseup
  211.  
  212. On mouseup
  213.     Open file filename
  214.     Write var to file filename
  215.     —Ex: Write field fieldname to file filename
  216.      —Ex: Write Msg to file filename
  217.      —Ex: Write the selection to file filename
  218.      Close file filename
  219. End mouseup
  220.  
  221. On mouseup
  222.     Open file filename
  223.     Repeat—Must read current file info then add new info & write it      out
  224.          Read from file filename for 16384
  225.         If it is empty then exit repeat
  226.         Put it after var1
  227.     End repeat
  228.     Put var2 & return after var1
  229.     Write var1 to file filename
  230.     Close file filename
  231. End mouseup
  232. ==========
  233. HyperCard Hints
  234. by Phil Wyman
  235.  
  236. 1.  The DoMenu command will execute DAs. For example, DoMenu “Calculator”.”
  237.  
  238. 2.  “It” is a local system variable, not a global.
  239.  
  240. 3.  “Set Cursor” command normally uses the following:
  241. “Set cursor to 1” = I-Beam
  242. “Set cursor to 2” = crossbar
  243. “Set cursor to 3” = thick crsbar
  244. “Set cursor to 4” = watch
  245. “Set cursor to 5” = arrow or                    browse tool
  246.  
  247. 4.  “Set lockmessages to true” does not work in the message box.  This is because “lockmessages” is turned off during idle. Therefore, lockmessages can only be used in a script.
  248.  
  249. 5.  If you don’t see the menu bar on an application, Command-Spacebar will allow you to see and use the menu bar.
  250.  
  251. 6.  Option-O both in and out of Fatbits will show you where opaque white exists on your card if you’re in Paint Tools.
  252.  
  253. 7.  Command-Drag sizes (elongates) a selected picture in HyperCard. Command-Shift-Drag will enlarge and shrink the selected picture proportionally.
  254.  
  255. 8.  When you are trying to intercept an arrowkey, you must use the message “on arrowkey” with the argument “var.”  Then you must see if “var” equals “left” or “right” or “up” or “down.” For example:
  256. on arrowkey var
  257.  if var = “left” then exit arrowkey
  258.  go next card
  259. end arrowkey
  260.  
  261. 9.  If you have to declare many global variables at the beginning of your script, you can declare them in the same line by separating them with a comma.  For example, “global var1,var2,var3,var4.”
  262.  
  263. 10.  You can edit your own patterns in the pattern windoid by double-clicking on them. These changed patterns will stay with the particular stack and not overlap into other stacks.
  264.  
  265. 11.  If a user-defined function uses the same name as a HyperCard function, HyperCard defaults to the user-defined function. For example, if you have a function “average” that you have defined in a stack script, HyperCard will use that function and not its own built-in average function.
  266. 12.  If you want a miniature picture of a card, you can do Copy Card from the menu, then Command-Shift-V to paste a miniature on your screen.
  267.  
  268. 13.  If you want to set more than one textstyle, you can say:   “set textstyle of button to bold,italic,underline.”  Also, if you want it to not have any textstyle after it has been set to a certain style,  you can say:  “set textstlyle of button to plain.”
  269.  
  270. 14.  The user pressing Command-Period can stop any script, even if an answer of ask dialog is on the screen. 
  271.  
  272. 15.  Double-clicking in the Script Editor or in a field selects the entire word.
  273.  
  274. 16.  In a script, you might not know how many levels deep you are in calls to other handlers that have called you.  “Exit to HyperCard”  will pop you out of all sub-messages.
  275. 17.  If you have had trouble getting the name of a card, here's the trick.  Go to the card and ask:  "get the short name of this card.”  The short name will give you the name of the card, whereas the long name will give you the entire pathway to the card.
  276.  
  277. 18.  “Repeat” or “Repeat Forever” will continue on until an exit repeat or an exit to HyperCard is encountered.
  278.  
  279. 19.  In a field, drag with the Command key on a selection of text.  HyperCard will put it into the message box, and you can then execute it by hitting return.
  280.  
  281. 20.  If the user cancels an “ask” dialog, HyperCard puts a null into the variable “it.”  You can therefore check and see if “it” is empty, thereby knowing that the user clicked CANCEL.
  282.  
  283. 21.  Once you have set a button to an icon, you can set the button to not have an icon by saying:  “set icon of button to zero.”
  284.  
  285. 22.  Only a locked text field can receive mouse messages such as mouseup, mousedown, mousewithin, etc.
  286.  
  287. 23.  The characters ≥ and ≤ work as HyperCard operators "greater than or equal" and “less than or equal”, as well as the more normal >= and <=.  You get these characters by pressing Option-Greater Than or Option-Less Than.
  288.  
  289. 24.  You can get rid of  your screen altogether by “set visible of cardwindow to false.”
  290.  
  291. 25.  Functions are not to be defined within message handlers.
  292.  
  293. ==========
  294. Programming Function Keys
  295. by Sioux Lacy
  296.  
  297. The HyperTalk command “functionkey” allows you to associate a script with any of the function keys on an extended keyboard.  To program a functionkey, use the following format:
  298.  
  299. On functionkey thekey
  300.     if thekey is 5 then
  301.           — add any script
  302.     end if
  303.  
  304.     if thekey is 6 then
  305.           put the heapspace — or whatever
  306.     end if
  307. end functionkey
  308.  
  309. You can put the script into a card, background, stack or home script, depending on how widely you want your functionkeys to be “detected.”  
  310.  
  311. The following script will make a functionkey that will automatically move anything selected on the card into the background.  The beauty of using type “x” with commandkey instead of domenu “cut” is that it transcends the fact that the Edit menu reflects the object selected. The command key simply calls that menu item, so it doesn’t matter if it says “cut button” or “cut picture.”   I’ve installed this script into my Home card, so that I can access it from any stack.
  312.  
  313. On functionkey
  314.     if whatkey is 6 then  
  315.         type “x” with commandkey -- Cut                 whatever is selected
  316.         domenu “background” -- enter the               background
  317.         type “v” with commandkey -- Paste it
  318.         domenu “background” — leave the               background
  319.     end if
  320. end functionkeys
  321. ==========
  322. ICONMAKER
  323.  
  324. As you know, HyperCard comes with many different button ICONs ready for your immediate use.  Just double-click on any button while in the Button Tool and you will see a dialog box with a button called Icon.  Clicking on this button allows you to scroll through and choose one of many interesting icons for your buttons.
  325. One thing users have wanted was the ability to create and install other icons in their stacks.  IconMaker™ solves that problem.  Now you can create Icons and put them into stacks very easily.  
  326. All you do is install IconMaker in your System file and select it from your DA menu.  An empty (32 X 32) ICON sized square appears and is capable of copying anything you click on within its boundaries.  ICN#s (Finder Icons) are created when you just click your mouse and ICONs are created if you press the command key and click.  
  327. ICON resources are what HyperCard uses.  You will be asked via Standard File where you want the ICON.  If you want to use it only in your personal stacks you can click on your Home card.  This makes the ICON available to all of your stacks that use your Home card.  If you want other people to enjoy your newly created ICON, you will have to install it directly into the stacks you will be sharing.
  328. Pressing on the H key with the Icon Maker selection square showing gives you HELP information.  Pressing any other key cancels Icon Maker.
  329.  
  330. IconMaker allows you to use clipart, or create your own art work and turn it into usable ICONs for sharing in five clicks of a mouse.  This is a really great utility for HyperCard.
  331.  
  332. Icon Maker 2.1 was created by Steve Fine.  I have spoken to Steve and he has allowed me to put Icon Maker 2.1 in the AHUG StackWare shareware folder.  You will be able to take it and see if it meets your needs just as you are invited to share in all of the stacks that we bring to our meetings every other Thursday.  Steve only asks that if you like it to please send him a contribution so that he may continue to develop useful tools for you.  His address is:
  333. Steve Fine
  334. 504 Linden Rd.
  335. University Park, PA 16802
  336. ==========
  337. TELL APPLE
  338. You can use this form to notify the HyperCard team of problems, bugs, and enhancement requests.
  339.  
  340.  
  341. Date:
  342. Name:
  343. MailStop or Address:
  344. Phone:
  345. Versions of:
  346.  a.  HyperCard
  347.  b.  Associated software
  348.  
  349.  c.  System Software
  350.     1. System
  351.     2. Finder
  352.     3. ImageWriter
  353.     4. LaserWriter file
  354.     5. Any others
  355.  
  356. Type of Macintosh:
  357. Peripherals:
  358. Description of problem, suggestions or comments:
  359.  
  360. ==========
  361. Vol 1 Number 3
  362.  
  363. In this third issue of WINDOID, we will continue to cover importing text into HyperCard™. Gary Bond, one of Apple’s outstanding HyperCard test team members, wrote a universal import button that takes into consideration nearly everything. You can now create a button that imports MacWrite™, Microsoft Word™, many database files, and even HyperCard stacks! We think you are going to enjoy this.
  364. Phil Wyman, another tester, has provided us with more of his highly acclaimed power-user tips and has taken a stab at explaining some of the more interesting aspects of HyperCard properties.
  365. In the two previous issues, there were some mistakes. I would like to apologize for any inconvenience or frustration they might have caused and rectify them. The errata will appear on page seven under WHOOPS. I generally get all the text stuffed into the WINDOID newsletter moments before the Thursday meeting, and sometimes I miss something. Many of the excellent scripters that avidly read WINDOID have noticed my lapses and have provided me with needed repairs. For their kind assistance, I offer my thanks.  
  366.  
  367. WINDOID provides an opportunity for its readers to contribute to the ongoing growth and excellence of HyperCard. With your assistance we can continue to bring to HyperCard added depth and functionality. In the back of every issue will be a form for you to keep by your Macintosh™. This form will allow you the unique opportunity to participate directly in the continued development of HyperCard.  
  368.  
  369. We will read all the forms returned and address questions that are being asked by HyperCard users. We will ask the team and provide you with an answer and publish the answers in this newsletter.  In this way we can gather information and provide for your needs in future versions of HyperCard.
  370.  
  371. WINDOID is trying to make a difference in the way that you work with HyperCard.  We need your input.  What sort of stacks are you using, what kinds of stacks are you creating, and what are some of the joys and frustrations you are experiencing.  We really want to know!
  372.  
  373. ERRATA -- ISSUE #1:  
  374.  
  375. In the first issue Gary Bond showed us how to find out which line of a scrolling field the user has clicked on. Apple employee Brian McGhie found a small flaw and wrote me the following letter:
  376.  
  377. The question was asked, “How can I find out which line of a field a user has clicked in?” The response was a method that would work in static fields, and then further developed into a method for scrolling fields. The function Clickline as given for scrolling windows only works if the scrolling field is (in pixels) an integer multiple of the textheight. A corrected version of Clickline appears below.
  378.  
  379. Function Clickline
  380.      return (trunc(((scroll of the target) ¬
  381.      + (item two of the clickloc) ¬
  382.      - (item two of the rect of the target)) ¬
  383.      div the textheight of the target) + one)
  384. End Clickline
  385.  
  386. The idea is to calculate the number of pixels from the top of the field to the position that you clicked on. So you take the number of pixels that have scrolled offscreen, and add in the vertical position of the mouseclick minus the vertical position of the top of the field. This sum is the total number of pixels from the logical top of the window —not the visual top. Divide by the height of the font to get the number of lines. Since this number is not always an integer, truncate it. The result is a zero based count of lines. Add one and return the correct line number that was clicked in.
  387.  
  388.  
  389. ERRATA -- ISSUE #2:  
  390.  
  391. Robin Shank provided us with a “How to Program FunctionKeys” in HyperTalk script. We left out a word, and the script will not work without it.  The script should read:
  392.  
  393. On functionkey whatkey
  394.     if whatkey is 6 then  
  395.     type "x" with commandkey  — Cut whatever is selected
  396.     domenu "background"       — enter the background
  397.     type "v" with commandkey  — Paste it
  398.     domenu "background"       — leave the background
  399.      else
  400.             pass functionkey
  401.      end if
  402. end functionkey
  403.  
  404. There are two other stacks on the StackWare™ server that deserve serious attention. The AIDS stack is a perfect representation of how HyperCard can be used in an incredibly invocative eye and heart grabbing style. This stack is not only visually and emotionally gripping, but is an excellent  example of how to use HyperCard as a powerful vehicle to move you through diverse information. You should get this stack. 
  405.  
  406. Finally, Tree Frog Studio software presents CheapSequencer.  Tree Frog has given us a music sequencer that must be seen and heard to be believed. These innovative stackware developers are interested in entertaining us with great graphics and functional stackware tools.  
  407. It’s stacks and people like these that really show the power and versatility of HyperCard.
  408.  
  409. We hope you have enjoyed reading WINDOID and have found it to be interesting and informative. We care enough to take the time to give you the most up-to-date information about HyperCard, and we would like to make a request for a little of your time. There is a form that follows this editorial; please fill it out if you will. We are very interested in hearing from you. What sort of stacks are you using, what kind of stacks are you creating, and what are your joys and frustrations in using HyperCard.  
  410.  
  411. You have the unique opportunity to communicate directly with Bill, Dan, and the entire HyperCard development team. We really want to know what you would like to see in HyperCard and are more than willing to give you what you want. What we need to make this happen is your input. Let us know what you think. We can address it in WINDOID or perhaps the next revision of HyperCard. You can make a difference in the world by communicating with us. Don’t pass up the opportunity!
  412. ==========
  413.  
  414. If you have a bug, suggestion, comment, or just want to know 
  415. the best way to do something in 
  416. HyperCard, you can fill out the form and send it to:  
  417. AHUG c/o David Leffler
  418. Apple Computer, Inc.
  419. MS/27-AQ
  420. 20525 Mariani Ave.
  421. Cupertino, CA 95014  
  422. Or copy the format and 
  423. Apple-Link™ it to: 
  424. HYPERBUG$
  425. ==========
  426.  
  427. Danny Goodman presents Focal Point
  428.  
  429. At the last Apple HyperCard User Group meeting , Danny Goodman, author of The Complete HyperCard Handbook, presented to an appreciative audience his incredible business productivity stack Focal Point™. It will be released soon by Activision™. We were all amazed at the incredible graphics and awesome features he has scripted into it. Danny, as you might know, is not a programmer and has always been frustrated by his inability to turn his ideas into software. HyperCard has empowered him to not only turn his ideas into reality, but to allow him the opportunity to share his ideas with the world. Thank you Danny!
  430.  
  431. Amanda Goodenough, author of the Inigo and My Favorite Camel series of wonderful adventures, was also on hand. Her obvious love of stories and great presentation style captivated the audience.  Amanda continues to enhance and produce more of these non-textual stories and has graciously allowed us to place them in an Amanda’s Stacks folder on the AHUG StackWare™ server. My Favorite Camel is a favorite of mine, and I think everyone should see it and share it with someone they love.
  432.  
  433. There is one other stack on the StackWare™ server that deserves serious attention. The AIDS stack is a perfect representation of how HyperCard can be used in an incredibly invocative eye and heart grabbing style. This stack is visually gripping and is an excellent  example of how to use HyperCard as a powerful vehicle to move you through diverse information. You should get this stack. 
  434.  
  435. ====================
  436.  
  437. HyperCard Hints
  438. by Phil Wyman
  439.  
  440. 1. If you get tired of pulling the Tools Windoid off of the menubar when you need it, try Option-Tab, which will tear it off for you!  Also, if the Tools Windoid is in a paint tool,  hitting Tab will tear off the Patterns Windoid.
  441.  
  442. 2. If you have a line in your script that is longer than the editor window, you can place an Option-Return at a space in the line to break it into two smaller lines.  The two lines will execute in the same way as the original line.  (Do not place the Option-Return into the middle of a quoted string. Also, if you use the Option-Return in a comment,  remember that every line of a comment must start with a double hyphen!)
  443.  
  444. 3. For those programmers out there who are used to "for next" loops, there is a "next repeat" command in HyperTalk which works in a repeat loop a lot like a "next" command in a "for next" loop.  The “next repeat” command does not execute anything that follows it in the repeat loop, but rather starts executing at the beginning of the repeat loop.  
  445.  
  446. Also, if you wish to exit the repeat loop altogether, without executing anymore of the lines in  the repeat loop, then use "exit repeat". 
  447.  
  448. Note:  If you want to exit the entire message handler from anywhere in the handler, use "exit <handlername>" (i.e., "exit mouseup").
  449. If you wish to leave the handler but wish the current message to be sent on up the hierarchical path from where it is now, then use "pass <handlername>". 
  450.  
  451. 4. When concatenating two strings,  you can add a space between the two strings by using two ampersands "&&" instead of just one "&".
  452.  
  453. 5. A shorthand for "button" in HyperTalk is "btn".  A shorthand for "background" is "bkgnd". 
  454.  
  455. 6. You can copy buttons, fields, backgrounds or cards between stacks.  This is a very powerful feature of HyperCard.
  456.  
  457. 7. For those of you with the regular size Mac Plus or Mac SE screens, try this for a thrill:
  458.       Set loc of cardWindow to 10,50
  459. You will see what people on large screens see all the time, a window title bar which states the pathname of the window you are viewing.  (To reset your cardWindow, "Set loc of cardWindow to 0,0".)
  460.  
  461. 8. If you are in any tool other than the Browse tool, you can return to the Browse tool by Command-Tab.
  462.  
  463. 9. When you are in the Button tool, you can Command-Drag to create a new button.  Option-Drag on a button and you will drag a copy of the button.
  464.  
  465. 10. A first attempt at a small treatise on the use of "the","of", and "()" in HyperTalk:
  466. In general, either "the", "of", or parentheses () are required to signal HyperTalk that a function or property is to be activated.
  467.  
  468.  
  469. PROPERTIES:
  470. With button, card, background, stack, and window properties, "the" is optional, but you need "of". Also, properties never have parentheses. You can say:
  471.     put hilite of button 1
  472.     put the hilite of button 1
  473.  
  474. Since there is no "of" to activate it, you cannot say:
  475.       put the hilite button 1
  476.  
  477. If you are using a global or painting property, you need "the", since there is no "of" to activate the property. For instance, you can say:
  478.     put the lockScreen
  479.     put the textAlign
  480.  
  481. However, you cannot put the property by saying:
  482.     put lockScreen
  483. because HyperCard will think you are using lockScreen as a variable, not a property.
  484.  
  485. FUNCTIONS:
  486.  
  487. Either "the", "of", or parentheses () are required with a function.
  488.  
  489. However, you cannot mix "the" with parentheses in a system function. For instance, you cannot say:
  490.     put the charToNum("a")
  491.  
  492.  You are allowed to say:
  493.     put the chartonum of "a"
  494.     put chartonum("a")
  495.       put the chartonum of ("a")
  496.     If a system function has more than one argument, it will always require parentheses.  For user-defined functions, you must always use parentheses, even if there are no arguments—i.e., userFunction().    
  497. If a function does not use "of" or "()", then "the" is required! For example, "date" doesn’t work without "the", since there is not an "of" or "()" to activate the function. You can say:
  498.      put the date
  499.  
  500. But you cannot say:
  501.      put date
  502. because HyperTalk will assume that "date" is a variable. This concept of insisting on a "the" to activate the function allows for future expansion of more system functions, since system functions will not be able to collide with variables that users already have in their scripts.
  503. ==========
  504.  
  505. The Universal Button
  506. by Gary Bond
  507.  
  508. Last issue we dealt with importing text. While those approaches are reliable, they are also very slow and don’t account 
  509. for a number of problems that might occur along the way. Consistent with our goal to provide you with the best, this issue contains a script for a universal import button which does both kinds of import (text and data). To use it, type it 
  510. into any button script.
  511.  
  512. In addition to importing text files it also imports Macwrite and Word documents and even Hypercard stacks! This 
  513. version of the import button fixes bugs both in Hypercard and in previous button versions. 
  514.  
  515.  
  516.  
  517. on mouseUp
  518.   global cardcount,startcard,memory,header
  519.   get userlevel
  520.   put it into item 1 of memory
  521.   set userlevel to 5
  522.   set lockmessages to true
  523.   set lockscreen to true
  524.   put short id of this card into startcard
  525.   answer "Import text file as:" with "Data" or "Text" or "Cancel"
  526.   if it is "Cancel"then Cleanexit
  527.   if it is "Text" then
  528.     answer "Include header information in fields?" with "Yes" or "No"
  529.     put it into header
  530.     Importext
  531.   else
  532.     Importdata
  533.   end if
  534.   go next card
  535.   Cleanexit "Compact"
  536. end mouseup
  537.  
  538. on importext
  539.   global cardcount,startcard,memory,header
  540.   put 0 into cardcount
  541.   repeat
  542.     ask "Name or pathname of text file to import:"  with item 2 of memory
  543.     if short name of this stack is in it then
  544.       if "," is not in memory then put "," after  memory
  545.       put it into item 2 of memory
  546.       answer "Can’t import current stack!"  with "Ok"
  547.       next repeat
  548.     end if
  549.     if it is empty then
  550.       Cleanexit
  551.     else
  552.       exit repeat
  553.     end if
  554.   end repeat
  555.   put it into filename
  556.   if "," is not in memory then put "," after memory
  557.   put it into item 2 of memory
  558.   set cursor to 4
  559.   open file filename
  560.   repeat
  561.     read from file filename for 16384
  562.     if it is empty and cardcount is 0 then
  563.       answer "Could not find file: " & filename with "Ok"
  564.       close file filename
  565.       Cleanexit
  566.     end if
  567.     if it is empty then exit repeat
  568.     put return after it
  569.     domenu "New card"
  570.     add 1 to cardcount
  571.     domenu "New field"
  572.     set name of card field (number of card fields) to "Import"
  573.     set style of card field "Import" to scrolling
  574.     drag from the loc of card field "Import" to 0,62
  575.     drag from 190,100 to 512,342
  576.     if header is "Yes" then
  577.       put "Characters:" && number of chars in it & return & return before it
  578.       put "Lines:" && number of lines in it & return before it
  579.       put "File:" && filename & return before it
  580.       put "Import card:" && cardcount & return before it
  581.     end if
  582.     put it into card field "Import"
  583.   end repeat
  584.   close file filename
  585.   if header is "Yes" then
  586.     repeat until the short id of this card is startcard
  587.       put "of" && cardcount after line 1 of card field "Import"
  588.       go previous card
  589.     end repeat
  590.   else
  591.     go card id startcard
  592.   end if
  593. end importext
  594.  
  595. on importdata
  596.   global filename,cardcount,startcard,memory,header
  597.   put empty into delimiters
  598.   put empty into filename
  599.   put 0 into cardcount
  600.   put 0 into limit
  601.   put 0 into fieldcount
  602.   repeat until delimiters is not empty
  603.     put 0 into nofields
  604.     answer "Use Tab and Return as delimiters?" with "Yes" or "Other" or "Cancel"
  605.     if it is "Cancel" then mouseup
  606.     if it is "Yes" then put "9,13" into delimiters
  607.     if it is "Other" then
  608.       repeat until ((item 1 of it > 0 and item 1 of it < 256)¬
  609.         and (item 2 of it > 0 and item 2 of it < 256)) or it is empty
  610.         ask "Enter two comma separated Ascii delimiters:" with empty
  611.         put it into delimiters
  612.       end repeat
  613.     end if
  614.   end repeat
  615.   if item 1 of delimiters is item 2 of delimiters then put 1 into nofields
  616.   answer "Include header information in fields?" with "Yes" or "No"
  617.   put it into header
  618.   repeat
  619.     ask "Name or pathname of text file to import:"  with item 2 of memory
  620.     if short name of this stack is in it then
  621.       if "," is not in memory then put "," after memory
  622.       put it into item 2 of memory
  623.       answer "Can’t import current stack!" with "Ok"
  624.       next repeat
  625.     end if
  626.     if it is empty then
  627.       if cardcount > 0 then
  628.         close file filename
  629.         CleanExit
  630.       end if
  631.       Importdata
  632.     else
  633.       exit repeat
  634.     end if
  635.   end repeat
  636.   put it into filename
  637.   if "," is not in memory then put "," after memory
  638.   put it into item 2 of memory
  639.   set cursor to 4
  640.   open file filename
  641.   repeat
  642.     read from file filename until (numtochar of item 2 of delimiters)
  643.     if it is empty and cardcount is 0 then
  644.       answer "Could not find file: " & filename with "Ok"
  645.       close file filename
  646.       Cleanexit
  647.     end if
  648.     if it is empty then exit repeat
  649.     if chartonum(last character of it) is not item 2 of delimiters then
  650.       put item 2 of delimiters into temp
  651.       if temp is 9 then put "Tab" into temp
  652.       if temp is 13 then put "Return" into temp
  653.       answer "Can’t find record delimiter: " && temp with "Ok"
  654.       close file filename
  655.       cleanexit
  656.     end if
  657.     put empty into last character of it
  658.     if (numtochar of item 1 of delimiters) is not in it and nofields is 0 then
  659.       put item 1 of delimiters into temp
  660.       if temp is 9 then put "Tab" into temp
  661.       if temp is 13 then put "Return" into temp
  662.       answer "Can’t find field delimiter: " && temp with "Help" or "Ok"
  663.       if it is "help" then
  664.         answer "Use double record delimiters for records..." with "Continue”
  665.         answer "with no field delimiters. Example: 13,13" with "Ok"
  666.       end if
  667.       close file filename
  668.       Cleanexit
  669.     end if
  670.     if (numtochar of item 1 of delimiters) is not "," and nofields is 0 then
  671.       repeat until (numtochar of item 1 of delimiters) is not in it
  672.         put "," into character offset((numtochar of item 1 of delimiters),it) of it
  673.       end repeat
  674.     end if
  675.     if cardcount is 0 then
  676.       domenu "New background"
  677.     else
  678.       domenu "New card"
  679.     end if
  680.     add 1 to cardcount
  681.     if nofields is 0 then
  682.       put the number of items in it into limit
  683.     else
  684.       put nofields into limit
  685.     end if
  686.     repeat with count = 1 to limit
  687.       if cardcount is 1 then
  688.         add 1 to fieldcount
  689.         if fieldcount < 125 then
  690.           domenu "New field"
  691.         else
  692.           answer "No more fields can be created!" with "Ok"
  693.           Cleanexit "Compact"
  694.         end if
  695.       end if
  696.       put "Field" & count into fieldname
  697.       set name of bkgnd field (number of bkgnd fields) to fieldname
  698.       set style of bkgnd field fieldname to scrolling
  699.       If nofields is 0 and header is "Yes" then
  700.         put "Field" && count && "of" && the number of items in it & return into bkgnd field fieldname
  701.         put "Record" && cardcount && "of file:" && filename & return & return after bkgnd field fieldname
  702.       end if
  703.       if nofields is 0 then
  704.         put item count of it & return after bkgnd field fieldname
  705.       else
  706.         put it & return after bkgnd field fieldname
  707.       end if
  708.     end repeat
  709.     choose browse tool
  710.   end repeat
  711.   close file filename
  712.   go card id startcard
  713. end importdata
  714.  
  715. on Cleanexit var
  716.   global memory
  717.   if param(1) is "compact" then
  718.     domenu "Compact stack"
  719.   end if
  720.   choose browse tool
  721.   set userlevel to item 1 of memory
  722.   set lockscreen to false
  723.   set lockmessages to false
  724.   exit to hypercard
  725. end Cleanexit
  726.  
  727. ==========
  728. Vol 1 Number 4
  729.  
  730.  
  731.  
  732. In the fourth issue of WINDOID, we address more of the many questions and problems people have sent in.  Quite a number of people have expressed interest in moving a group of buttons or fields on a card.  Sioux Lacy, one of our outstanding HyperCard testers, has given us a way to group buttons and/or fields and move them, in a group, within a card and even onto other cards.  Sioux has also written for us an article on Finding multi-word strings in blocks of text.  This is one that everyone has asked for.
  733.  
  734. Phil Wyman, with assistance from Steve All, two more great HyperCard testers, have given us further HyperCard user tips.  We really appreciate all of the cards people have sent us with the tips they have found.  In this way we can pass on useful tips to many hundreds of HyperCard users.
  735.  
  736. Paul Foraker, our newest tester, has submitted an AutoLink script.  Using this great little shortcut for scripting buttons gives you another productivity tip I am sure you will find interesting.
  737.  
  738. Steve Maller has done it again!  ResCopy is his latest XCMD effort to give us a safe, elegant, and easy way to move resources around in HyperCard.  This version is his “shipping” version and does not have a time bomb in it.  You are free to give it away to your HyperCarding friends.  This is one stack that people who do not have it will lust for.
  739.  
  740. Sioux Lacy has given us Groupies 1.3, featured in this issue of WINDOID.  This is a must stack for serious HyperCard users.  I really appreciate Sioux’s efforts in bringing us all of these great articles and I am equally sure that you will also.
  741.  
  742. These two stack are on the Apple HyperCard User Group file server and can be obtained only here in Cupertino.  If your favorite bulletin board does not have them, please ask them to have someone upload them.
  743. ==========
  744. AutoLink
  745. by Paul Foraker
  746.  
  747. Shortly after you get HyperCard installed on your hard disk, you may notice that you are collecting a large number of other people’s stacks. One way of keeping track of all of them is to stuff them into a folder and put a button for them on a card in your Home stack. Since the original Home card already comes with 19 buttons (and room for about 24), you might want to make another card for holding buttons that take you to your miscellaneous stacks. To avoid having to name and link all the buttons on a new card to the stacks I’ve collected, I wrote a variation on Danny Goodman’s script which takes you to a stack even though the button has no script or link.
  748.  
  749. In this version, a button named “new button” opens the familiar Standard File dialog and then gets the name of whatever stack you select, changes the name of itself (the button) to the selected stack, then goes there.  If the button already has a name (other than “new button”), the script simply goes to the stack.  This eliminates the necessity for linking or scripting multiple buttons on a card.
  750.  
  751. To start from scratch from your Home card, select New Card (CMD-N) and title the new card “BackYard” (or anything else fun). Type the script below into the script window for the card.  (You can skip over typing the comments if you wish.) Then make a new button (you can select an icon for it — I use the generic stack icon). Now hold down the Option key and drag copies of the “new button” around onto your card.  (You can use the Shift key to constrain the movement so they’re lined up neatly.)   
  752.  
  753. Next, select the Browse tool again and click on one of your new buttons. You’ll get Standard File asking you “where 
  754. is the stack you want?”  Double click on one of the stacks in the list, the new button will get a name change, and 
  755. you’ll be off to the new stack. From there, you can hit the escape (~) key to go right back to the BackYard to AutoLink another button.
  756.  
  757. --AutoLink script
  758. --variation on Danny Goodman’s script
  759. --by Paul Foraker
  760.  
  761. on mouseUp
  762.   put the short name of this stack ¬
  763.   into thisStack                    --saving the name for 
  764.                                     --use later
  765.    get the short name of the target --puts the ‘short’ name of the 
  766.                                     --button you clicked on into ‘it’
  767.    if it is “new button” then       --Oh boy... a new stack has arrived!
  768.      push card                      --saves the BackYard card id 
  769.                                     --so we can come back to it
  770.      set lockMessages to true       --stops any other scripts from running
  771.      set lockScreen to true         --freezes the screen so we’re not 
  772.                                     --distracted by fast moving cards.
  773.      go stack “the stack you want?” --since there is no stack by that
  774.                                     --name, HyperCard will respond by 
  775.                                     --asking you where it is.
  776.                                     --Standard File will open and you 
  777.                                     --can select a stack
  778.                                     --or click on Cancel.
  779.      get the short name of this stack    --here we’re asking for the
  780.                                          --short name of the ‘new’ stack
  781.  
  782.     if it is thisStack then    --checking for clicking on the Cancel button
  783.        pop card                       --go back to our BackYard card
  784.        set lockScreen to false        --unlocking the screen display
  785.        exit mouseUp                   --pretend it never happened
  786.      end if                           --end of checking for ‘cancel’
  787.      
  788.     put it into stackName      --putting short name of the stack into 
  789.                                --’stackName’
  790.      pop card                  --go back to our BackYard card
  791.      set the name of the target to stackName      --rename the button
  792.      set showName of the target to true         --we want to see the name
  793.      set the script of the target to empty  --make sure there’s no script in
  794.                                             --the button
  795.      set lockScreen to false           --unlocking the screen display
  796.      set lockMessages to false         --now messages can fly around again.
  797.    end if                              --marks the end of the loop
  798.                                        --for a ‘new button.’
  799.  
  800.    --now, we make sure you didn’t click on the card or background:
  801.      if the short name of target is the short name of this card then exit mouseUp
  802.      if the short name of target is the short name of this bkgnd then exit mouseUp
  803.  
  804.    visual iris open to black      --just for fun
  805.    go STACK it                    --‘it’ will be either the new stack or
  806.                                   —one that’s already been identified
  807.    end mouseUp
  808. ==========
  809. HyperCard Hints
  810. by Phil Wyman
  811.  
  812. 1.     There are some interesting properties in HyperTalk that you may not know about:
  813.  
  814. a.  <the version> is a global property which tells you which version of HyperCard you are currently using.  This property will become very useful after new versions are released. Since the new versions will have added features that old versions do not understand, stack developers will want to check to see if their stack is currently running on a version of HyperCard that supports those new features.
  815.  
  816. b.  <the name> is another global property. It will tell you that the name of the program is HyperCard. I have not found a way to use this yet, so if anyone has any ideas, let me know.
  817.  
  818. c.  <the diskspace> is a global property which will tell you how many bytes you have left on the drive that the current stack is located on.
  819.  
  820. 2.    You can send a message up the heirarchy manually by using the message box.  For instance, if you want an OPENSTACK message sent without having to reopen your stack, just type OPENSTACK into the message box and hit return or enter. Any handler, starting with any handler in the current card, which uses OPENSTACK, will receive that message.
  821.  
  822. Some users are having trouble sending their own messages. In a script, you can just type the name of your message on a line by itself and that message will be sent. If HyperCard does not find a handler with that message, it will throw up a dialog telling you it can’t understand <message>.
  823.  
  824. You can also send a message with the <send> command. You can have difficulty with the <send> command if you are trying to send across stacks. Try going to the stack first before using <send>. For example:
  825. send mouseup to button 1¬ of card 1 of stack "Home"
  826. will generate a HyperCard error "expected end of line after send". To get the "mouseup"  message to the button, try this:
  827. go to card 1 of stack "Home"
  828. send mouseup to button 1
  829.     
  830. 3.    When you are printing your script from the script editor, you do not have to print the whole script. If you want to just print a portion of your script, then select the part you want, then click on the print button. Only your selected text will print.
  831.  
  832. 4.   The Tab key moves you between fields on a card in the order of their field number (which can be changed with Bring Closer and Send Farther).  But a useful fact for data entry is that Shift-Tab navigates you through fields in reverse order.
  833.  
  834. 5.   Choosing a selection with the Selection tool can leave you with a lot of extra white space surrounding your selection.  And you may already know that Command-S shrinks a selection rectangle until there is no surrounding white space.  What if you want a rectangular selection but no extra white space?  Hold down the Command key before selecting with the Selection tool and just that will happen.
  835.  
  836. 6.   If you are writing commercial stacks and need to restrict the user-level, you may wish to tell users in your About Box that they can access “Full Menus” by holding down the Command key before clicking the menu.
  837.  
  838. 7.   So you think that those tiny pictures in “Recent” are neat?  You can create them yourself.  Copy a card and hold down the Shift key when pasting it back in.  You’ll get an image of the card in miniature (but no actions from buttons or fields to type into).
  839.  
  840. There are three ways in which the script writer can inquire about the presence of a string in a block of text:  FIND, CONTAINS and OFFSET.  
  841. These can be used separately or in combination.
  842. The FIND command will highlight the next occurence of the first word of the string if all words in the string are somewhere on the card.
  843. Another option is to test if a particular container (field or variable) CONTAINS the string.
  844. This test will determine an exact match on the entire string.
  845. The function OFFSET will return the character in the container on which the match begins.  This can also be used to test IF the field/variable includes the string, since if it does NOT, offset will return 0.  Depending on the context of the search, the script writer may opt for one or a combination of these.  If the scope of the search is small, and across known fields, CONTAINS or OFFSET can be used.  However, if the search is across many fields in a large stack, FIND is a good mechanism to narrow down the number of fields that have to be examined to see if they CONTAIN the string.
  846.  
  847. To FIND a multi-word string
  848.  
  849. For example, you would like to find an exact match for the string “Hello there”.   You will discover that HyperCard is generous in its find criteria, and also matches the following:  “Hello world.  Is there life out there?”  
  850.  
  851. This can be problematic if the search is taking place inside a handler, rather than at the control of a human who can continue to hit the return key.   The way to circumvent this is to do your match in 2 steps.  Supposing you expect the match to be in a background field, try calling a function (until you’ve searched the entire stack) that does this:
  852.  
  853. function multiWordFind string
  854.    repeat with x = 1 to the number of bkgnd fields                      
  855.        if field x contains string then return "FOUND in field " & x
  856.    end repeat
  857.    return "NOT FOUND"
  858. end multiWordFind
  859.  
  860. (If you expected the match to be in a card field, repeat also for the number of card fields.)
  861.  
  862. on searchStackFor string
  863.      set lockScreen to true
  864.      find string
  865.      if the result is "Not Found" then cleanExit¬              
  866.      "This stack doesn’t contain: " & string
  867.                   --Use the above two lines or use the script
  868.                     --at the end as an alternate to find offset.
  869.      put the id of this card into startedHere
  870.      repeat
  871.        get multiWordFind (string)
  872.        if word 1 of it is "FOUND" then cleanExit it
  873.        go next card -- so a subsequent find won’t find the same              
  874.                     -- card over again                                
  875.        find string
  876.        if the id of this card is startedHere then cleanExit¬                         "This stack doesn’t contain: " & string
  877.      end repeat
  878. end searchStackFor
  879.  
  880. on cleanExit prompt
  881.    put prompt
  882.    set lockScreen to false
  883.    exit to HyperCard
  884. end cleanExit
  885.  
  886.       --Use the following as an alternate to determine the offset.
  887.  
  888. if word 1 of it is "FOUND" then 
  889.    cleanExit it && "at character position" && offset¬
  890.    (string, the value of word 3 to 4 of it)
  891. end if
  892.  
  893. ====================
  894. Grouping Buttons
  895. by Sioux Lacy
  896.  
  897. Sioux Lacy, one of the outstanding HyperCard testers, has donated this script to provide you, the user, an often-desired script for moving a group of buttons and/or fields around on a card.  We are always trying to give you what you ask for, so please let us know if this script is helpful to you. --Editor
  898.  
  899. Many users have asked about grouping objects.  This stack presents a method for assigning to a group any number of buttons or fields, and then being able to move that group as a unit, or copying and pasting that group onto another card.  This is accomplished with a series of handlers in a card field, called “menuField”.  It looks somewhat like a menu, accepts clicks on any command that it displays, and can be copied and pasted onto another card.
  900.  
  901. The menuField has a Help option that allows the user to read about each of its options.
  902.  
  903. Note that the menuField needs to be a card field in order to work properly.  And, when a group has been pasted, it will require re-grouping if its group identity is to work in the new context.  Also, since it is difficult to select overlapping objects to be members of a group, it is recommended that they be positioned so they don't overlap. 
  904.  
  905. Groupies 1.3 by Sioux Lacy, November 6, 1987.  AppleLink comments to me at LACY1, or send mail to Sioux Lacy, 
  906. MS 27-AQ, 20525 Mariani Ave., Cupertino, CA 95014.  
  907.  
  908. --Groupies 1.3 by Sioux Lacy
  909. --November 6, 1987
  910.  
  911. on NewField
  912.   get editBkgnd
  913.   if it is true then
  914.     set editBkgnd to false
  915.     put "The menuField cannot be a bkgnd field." &&  
  916.     "Delete this field & paste again.."
  917.     exit New Field
  918.   end if
  919.   put "Help" & return & "Group" & return & "Move" & return ¬
  920.   & "Copy" & return & "Paste" & return & "Clear" & return ¬
  921.   into card field id (the id of me)
  922.   choose browse tool
  923. end NewField
  924.  
  925. on mouseUp
  926.   put the id of me into myID
  927.   put the mouseV into clickLoc
  928.   put "HelpMe,NewGroup,MoveGroup,CopyGroup,PasteGroup,ClearGroup" ¬
  929.   into messages
  930.   repeat with x = 1 to the number of lines in card field id myID
  931.     put "" into char 1 of line x of card field id myID
  932.   end repeat
  933.   put the textHeight of me into height
  934.   put item 2 of the rect of me + height into baseLine
  935.   repeat with x = 1 to the number of lines in card field id myID
  936.     if clickLoc < baseLine then
  937.       put "√" into char 1 of line x of card field id myID
  938.       send item x of messages to me
  939.       exit mouseUp
  940.     end if
  941.     add height to baseLine
  942.   end repeat
  943. end mouseUp
  944.  
  945. on HelpMe
  946.   ask "Which option would you like help on?" with "Group"
  947.   if it is empty then exit HelpMe
  948.   if it is "Group" then
  949.     put "This option will let you specify objects to be grouped.
  950.   else if it is "Move" then
  951.     put "This option will let you move the group."
  952.   else if it is "Copy" then
  953.     put "This option used in conjunction with Paste will copy" && ¬
  954.     "& paste the group."
  955.   else if it is "Paste" then
  956.     put "This option used in conjunction with Copy will copy" && ¬
  957.     "& paste the group."
  958.   else if it is "Clear" then
  959.     put "This option will delete all the objects in the group."
  960.   else put "Never heard of that option.”
  961. end HelpMe
  962.  
  963. on NewGroup
  964.   global objectList
  965.   put "Shift-click to include objects in group. Option-click when done."
  966.   put empty into objectList
  967.   repeat
  968.     set cursor to 2
  969.     wait until the mouseClick
  970.     put the mouseLoc into thisClick
  971.     set cursor to 4
  972.     if the optionKey is down then exit repeat
  973.     repeat with x = the number of card buttons down to 1
  974.      if isClickWithinObject (thisClick, rect of card btn x) then
  975.       put "card btn id " & the id of card btn x & "," after objectList
  976.       exit repeat
  977.     end if
  978.     end repeat
  979.     repeat with x = the number of bkgnd buttons down to 1    
  980.         if isClickWithinObject (thisClick, rect of bkgnd btn x) then
  981.       put "bkgnd btn id " & the id of bkgnd btn x & "," after objectList
  982.       exit repeat
  983.     end if 
  984.     end repeat
  985.     repeat with x = the number of card fields down to 1    
  986.         if isClickWithinObject (thisClick, rect of card field x) then
  987.       put "card field id " & the id of card field x & "," after objectList
  988.       exit repeat
  989.     end if 
  990.     end repeat
  991.     repeat with x = the number of bkgnd fields down to 1    
  992.         if isClickWithinObject (thisClick, rect of bkgnd field x) then
  993.       put "bkgnd field id " & the id of bkgnd field x & "," after objectList
  994.       exit repeat
  995.     end if 
  996.     end repeat
  997.   end repeat     
  998.   put empty into last char of objectList
  999.   put "The group consists of: " & objectList
  1000. end NewGroup
  1001.  
  1002. function isClickWithinObject thisClick, theRect
  1003.   if ((item 1 of theRect) <= (item 1 of thisClick)) and ¬
  1004.   ((item 2 of theRect) <= (item 2 of thisClick)) and ¬
  1005.   ((item 3 of theRect) >= (item 1 of thisClick)) and ¬
  1006.   ((item 4 of theRect) >= (item 2 of thisClick)) then
  1007.     return true  
  1008.   else return false
  1009. end isClickWithinObject
  1010.    
  1011. on MoveGroup
  1012.   global objectList
  1013.   if objectList is empty then
  1014.     put "There are no objects in the group."
  1015.     exit MoveGroup
  1016.   end if
  1017.   put "Click and drag the group with mouse down. There is an initial delay."
  1018.   wait until the mouseClick
  1019.   put the mouseLoc into myLoc
  1020.   set cursor to 4
  1021.   put empty into horizontalOffset
  1022.   put empty into verticalOffset
  1023.   repeat with i = 1 to the number of items in objectList
  1024.     put the location of item i of objectList into theLoc
  1025.     put item 1 of theLoc - item 1 of myLoc & "," after horizontalOffset
  1026.     put item 2 of theLoc - item 2 of myLoc & "," after verticalOffset
  1027.   end repeat
  1028.   put empty into last char of horizontalOffset
  1029.   put empty into last char of verticalOffset
  1030.   set cursor to 2
  1031.   repeat while the mouse is down
  1032.     get the mouseLoc
  1033.     repeat with i = 1 to the number of items in objectList
  1034.       put it into theLoc
  1035.       add item i of horizontalOffset to item 1 of theLoc
  1036.       add item i of verticalOffset to item 2 of theLoc
  1037.       set location of item i of objectList to theLoc
  1038.     end repeat
  1039.   end repeat
  1040. end MoveGroup
  1041.  
  1042. on CopyGroup
  1043.   global WhereTheGroupIs
  1044.   set lockScreen to true
  1045.   choose field tool
  1046.   click at the location of me
  1047.   doMenu "Copy Field"
  1048.   choose browse tool
  1049.   put the long id of this card into WhereTheGroupIs
  1050.   put "Go to another card, type cmd-V, & choose Paste from the menuField."
  1051.   set lockScreen to false
  1052. end CopyGroup
  1053.  
  1054. on PasteGroup
  1055.   global whereTheGroupIs, objectList
  1056.   if whereTheGroupIs = empty then put "Please choose Copy from the menuField."
  1057.   else if objectList = empty then put "There are no objects in the group."
  1058.   else
  1059.     set cursor to 4
  1060.     set lockMessages to true
  1061.     set lockScreen to true
  1062.     repeat with i = 1 to the number of items in objectList
  1063.       push this card
  1064.       go to WhereTheGroupIs
  1065.       get item i of objectList
  1066.       if word 2 of it is "btn" then choose button tool
  1067.       else choose field tool
  1068.     if word 1 of it is "bkgnd" then set editBkgnd to true
  1069.       click at the location of it
  1070.       type "C" with commandKey
  1071.       pop card
  1072.       type "V" with commandKey
  1073.     set editBkgnd to false
  1074.     end repeat  
  1075.     choose browse tool
  1076.     put "To group these new objects, " & ¬
  1077.      "choose Group from the menuField."
  1078.     set lockScreen to false
  1079.   end if
  1080. end PasteGroup
  1081.  
  1082. on ClearGroup
  1083.   global objectList
  1084.   put "The group consists of: " & objectList
  1085.   answer "Clearing group is not undoable. Are you sure?" ¬
  1086.   with "Yes" or "Cancel"
  1087.   if it is "Cancel" then exit ClearGroup
  1088.   repeat with i = the number of items in objectList down to 1
  1089.     get item i of objectList
  1090.     if word 2 of it is "btn" then choose button tool
  1091.     else choose field tool
  1092.     click at the location of it
  1093.     type "X" with commandKey
  1094.   end repeat
  1095.   choose browse tool
  1096.   put empty into objectList
  1097. end ClearGroup
  1098.  
  1099.  
  1100.